package com.superlistaportable.productList;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.content.Intent;
import android.os.Bundle;

public class ProductListModel {
    List<String> listDataHeader;
    HashMap<String, List<String>> listDataChild;
    HashMap<String, Float> itemCost = new HashMap<String, Float>();
    HashMap<String, Integer> itemStock = new HashMap<String, Integer>();
    private HashMap<String, List<String>> savedList;
    private String selectedSupermarket;
    
    public ProductListModel(Intent i){
    	Bundle extras = i.getExtras();
		if (extras != null) {
			selectedSupermarket = extras.getString("selectedSupermarket");
        }
		if(savedList == null){//Si no habia nada, agrego una entrada que pida actualizar la lista
			HashMap<String,List<String>> firstTimeList= new HashMap<String,List<String>>();
			List<String> messages = new ArrayList<String>();
			messages.add("Por favor, actualice la lista para continuar");
			itemCost.put("Por favor, actualice la lista para continuar", 2.0f);
			firstTimeList.put("Actualice la lista",messages );
			savedList = firstTimeList;
		}
			loadListDataFrom(savedList);
    }
    
    public void buildSavedListAndItemCost(String responseFromServer){
    	List<String> groups = new ArrayList<String>();
    	List<Product> products = new ArrayList<Product>();
		try {	
			XmlPullParserFactory pullParserFactory;
			try {
				pullParserFactory = XmlPullParserFactory.newInstance();
				XmlPullParser parser = pullParserFactory.newPullParser();
			        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
		            parser.setInput(new StringReader (responseFromServer));
		            parseXML(parser,products,groups);

			} catch (XmlPullParserException e) {
				e.printStackTrace();
			}
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		 catch (IOException e) {
			e.printStackTrace();
		}
		generateGroupAndItems(products,groups);//Asigno los productos a sus grupos
		generateItemCosts(products);//Asigno todos los precios a los productos
		loadListDataFrom(savedList);//Preparo la lista con los valores para que se muestre actualizada
    }
    
    private void generateGroupAndItems(List<Product> products, List<String>groups){
    	if(products != null & groups != null){
    		//borro los valores anteriores
    		savedList.clear();
    	}
    	for(String group : groups){
    		//Fue necesario crear este metodo para que se cree una nueva List<String> por cada llamado
    		//de lo contrario, al cambiar el valor de la lista,cambia su valor en el hashmap, aunque
    		//ya haya sido insertado con anterioridad
    			insertGroupNamesInSavedList(products,group);
    		}
    }
    
    private void insertGroupNamesInSavedList(List<Product> products, String group){
    	List<String> currentProductNames=new ArrayList<String>();
    	for(Product product : products){
    		if(product.group.equals(group)){
    			currentProductNames.add(product.name +" "+product.brand);
    			}
    	}
    	savedList.put(group, currentProductNames);
    }
    
    private void generateItemCosts(List<Product> products){
    	if(products != null){
    		//borro los valores anteriores
    		itemCost.clear();
    	}
    	for(Product currentProduct : products){
    		itemCost.put(currentProduct.name+" "+currentProduct.brand, Float.parseFloat(currentProduct.cost));
    	}
    }
    
    private class Product
    {
    	public String group;
    	public String name;
    	public String brand;
    	public String cost;

    }
    private void parseXML(XmlPullParser parser,List<Product>products,List<String> groups) throws XmlPullParserException,IOException
	{
        int eventType = parser.getEventType();
        Product currentProduct = null;
        String currentGroup="";
        boolean isItem = false;

        while (eventType != XmlPullParser.END_DOCUMENT){
            String name = null;
            switch (eventType){
                case XmlPullParser.START_DOCUMENT:
                    break;
                case XmlPullParser.START_TAG:
                    name = parser.getName();
                    if (name.equals("item")){
                        currentProduct = new Product();
                    }else if(name.equals("group")){//Si lei un grupo,va no va a venir un item
                    	isItem = false;
                    }else if (!isItem){//Si no es item,es el nombre del grupo
                        if (name.equals("name")){
                        	String text = parser.nextText();
                        	groups.add(text);
                        	currentGroup = text;
                        	isItem = true;//Lo proximo que va a venir es un item,porque no hay grupos vacios
                        } 
                    }else if (currentProduct != null & isItem){
                    	if(name.equals("name")){//Asigno el nombre del item actual
                    		currentProduct.name = parser.nextText();
                        } else if (name.equals("brand")){//Asigno la marca del item actual
                            currentProduct.brand= parser.nextText();
                        } else if(name.equals("cost")){//Asigno el costo del item actual
                        	currentProduct.cost = parser.nextText();
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    name = parser.getName();
                    if (name.equalsIgnoreCase("item") && currentProduct != null){
                    	currentProduct.group = currentGroup;
                    	products.add(currentProduct);
                    	currentProduct = new Product();
                    } 
            }
            eventType = parser.next();
        }
        
	}
 
    
    
	public List<String> getItemsWithStock(){
		ArrayList<String> itemsWithStock = new ArrayList<String>();
		for(Entry<String, Integer>  entry: itemStock.entrySet()){
    		if(entry.getValue() > 0){
    			itemsWithStock.add(entry.getKey());
    		}
		}
		return itemsWithStock;
	}
	
	public float[] getTotals() {
		List<String> itemsWithStock = getItemsWithStock();
		float[] totals = new float[itemsWithStock.size()];
		for(int i = 0; i < itemsWithStock.size(); i++){
			totals[i] = totalCostOf(itemsWithStock.get(i)); 
		}
		return totals;
	}


    private void loadListDataFrom(HashMap<String, List<String>> updates) {
    	//TEMPORAL
    	//cargar la lista de algun lado y llamar a reloadList..
    	
        listDataHeader = new ArrayList<String>();
        listDataChild = new HashMap<String, List<String>>();
 
		for(String key : updates.keySet()){
			listDataHeader.add(key);
		}
		
		for(Entry<String, List<String>> entry : updates.entrySet()){
			listDataChild.put(entry.getKey(), entry.getValue());
		}
		
		buildItemStockMap();

    }
    
	private void buildItemStockMap() {
		this.itemStock = new HashMap<String, Integer>();
        for (String s : listDataHeader) {
        	for(String c: listDataChild.get(s)){
        		this.itemStock.put(c, 0);
        	}
		}
	}


	public String getResponseFromServer(String url) {	
		  String response = "";
              DefaultHttpClient client = new DefaultHttpClient();
              HttpGet httpGet = new HttpGet(url);
              try {
                  HttpResponse execute = client.execute(httpGet);
                  InputStream content = execute.getEntity().getContent();

                  BufferedReader buffer = new BufferedReader(
                          new InputStreamReader(content));
                  String s = "";
                  while ((s = buffer.readLine()) != null) {
                      response += s;
                  }

              } catch (Exception e) {
                  e.printStackTrace();
                  return "Error al acceder al server";
              }
          buildSavedListAndItemCost(response);
          return response;
	}

   
	public List<String> getListHeaders(){
		return listDataHeader;
	}
	
	public HashMap<String, List<String>> getListChildren(){
		return listDataChild;
	}

	public HashMap<String, Integer> getItemStock() {
		return itemStock;
	}

	public float costOf(int row, int col) {
		return itemCost.get(getItemName(row, col));
	}

	public int stockOf(int row, int col) {
		return itemStock.get(getItemName(row, col));
	}

	public float totalCostOf(String name) {
		return itemCost.get(name)*itemStock.get(name);
	}

	private String getItemName(int row, int col) {
		return listDataChild.get(listDataHeader.get(row)).get(col);
	}
	
	public void addStockTo(int row, int col) {
		itemStock.put(getItemName(row, col), itemStock.get(getItemName(row, col))+1);
	}

	public void removeStockTo(int row, int col) {
		if(itemStock.get(getItemName(row, col)) > 0)
			itemStock.put(getItemName(row, col), itemStock.get(getItemName(row, col))-1);
	}
	public HashMap<String, List<String>> getSavedList(){
		return savedList;
	}
	public HashMap<String, Float> getItemCost(){
		return itemCost;
	}

}
